home *** CD-ROM | disk | FTP | other *** search
/ The Business Master (3rd Edition) / The Business Master (3rd Edition).iso / files / utilreen / cutpast4 / cutpast4.asm next >
Encoding:
Assembly Source File  |  1988-04-08  |  25.0 KB  |  872 lines

  1.       PAGE 55,132
  2.       TITLE CUTPASTE 4.0                                               ; WARREN
  3. ;
  4. ; CUTPASTE -
  5. ;      Permission is granted to copy and distribute freely copies of this
  6. ;      program with the following restrictions:
  7. ;
  8. ;      1) this program be passed in the public domain
  9. ;      2) a fee, beyond the cost of the disk, not be charged
  10. ;      3) improvements under the name of CUTPASTE not be passed on 
  11. ;         but rather sent to us to check for possible incompatibilities 
  12. ;         with other programs
  13. ;
  14. ;   Larry Weiss, Gerry Boyd, (Stephen) Randy Davis
  15. ;   (214) 238-9545  POB 831420 Richardson, Texas 75083           
  16.  
  17. ; version 4.0 differs from 3.0 only in that the cursor position is NOT ; WARREN
  18. ;   modified on entry.  This was because of a request by Robert Warren ; WARREN
  19. ;   for such a version. See the comments marked WARREN.                ; WARREN
  20.       
  21. ;PARAMETERS -- MOST OF THESE MAY BE CHANGED TO ANY DESIRED VALUE
  22.  
  23. wndw_ht    equ 25             ;the size of the screen
  24. wndw_wd    equ 80
  25. cut_key    equ  07000H        ;scan code - ascii of cut (Alt-F9)
  26. paste_key  equ  06600H        ;scan code - ascii of paste (Cntrl-F9)
  27.                                 ;now scan codes of edit keys
  28. up_arrow   equ  4800H
  29. down_arrow equ  5000H
  30. left_arrow equ  4B00H
  31. right_arrow equ 4D00H
  32. del_left   equ  0008H         ;user rubout (^H) key
  33. delete     equ  5300H         ;use del (lower right)
  34. insert     equ  5200H
  35. cr         equ  000DH
  36. home       equ  4700H
  37. escape     equ  001BH
  38. tab        equ  7400H         ; ^right arrow
  39. rev_tab    equ  7300H         ; ^left arrow
  40. line_ins   equ  5100H         ;pg down
  41. line_del   equ  4900H         ;pg up
  42. mark_char  equ  4F00H         ;end key
  43.  
  44. blank      equ  00720H       ;define the character which is a blank
  45. attrib     equ  007H         ;and our default attribute (should agree with blank)
  46. video      equ  10H          ;video BIOS call
  47. inv_attrib equ  070H         ;inverse of 'attrib'
  48.     PAGE
  49. CSEG  SEGMENT PARA PUBLIC 'CODE'
  50.       ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:NOTHING   ;STANDARD DECL FOR .COM FILE
  51.  
  52.       ORG  100H
  53.  
  54. Start:
  55.       JMP INSTALL
  56.  
  57. ;PLACE DATA AREA HERE FOR READABILITY
  58.  
  59. SCREENSAVE: DW (WNDW_HT * (WNDW_WD+1)) DUP (BLANK);RESERVE SPACE TO SAVE OPENED WINDOW
  60. LINESAVE:   DW WNDW_WD DUP (BLANK) ;BUFFER FOR LINE DELETE
  61.  
  62. CURSOR_POS  DW 0
  63. OLD_CUR_POS DW 0
  64. SAVESTACK   DW 0,0
  65.  
  66. REQUEST     DW 0              ;REQUEST TYPE
  67.  
  68. KEY_RQST_HANDLER DD 0         ;ADDRESS OF THE ORIGINAL KEYBOARD REQUEST HANDLER
  69.  
  70. LEFT_MARG  DB   00            ;define the confines of the window
  71. RIGHT_MARG DB   00
  72. TOP_MARG   DB   00
  73. BOT_MARG   DB   00
  74. UPPER_LEFT DW   00
  75.  
  76. MARK       DW   -1            ;FLAGS USED IN CHARACTER FEED
  77. FEED_START DW   00            ;ADDRESS IN BUFFER OF BEGIN...
  78. FEED_STOP  DW   00            ;...AND END OF FEED
  79. FEED_END1  DW   00            ;TEMP HOLDING SPOT FOR BEG FEED ADDR
  80. FEED_END2  DW   00            ;TEMP HOLDING SPOT FOR END FEED ADDR
  81.  
  82. FEED_CHAR  DW   00            ;CHAR TO FEED ON THIS CALL
  83.  
  84. DISPLAY_SEG DW 00             ;SAVE OFF THE DISPLAY SEGMENT ***
  85. PAGE
  86. BEGIN PROC FAR                ;FAR LABEL SINCE ITS ENTERED BY INTERRUPT
  87. MAINLOOP:
  88.       MOV  CS:REQUEST,AX      ;SAVE HIS AX REGISTER
  89.  
  90.       MOV  AX,CS:FEED_START   ;ARE WE IN THE MIDDLE OF FEEDING CHARS...
  91.       CMP  AX,CS:FEED_STOP    ;...TO THE APPLICATION?
  92.       JZ   NOFEED             ;NO
  93.       JMP  FEED               ;YES
  94. NOFEED:
  95.       MOV  AX,CS:REQUEST      ;RESTORE USERS AX
  96.       PUSHF                   ;CALL OLD INTERRUPT HANDLER (EMULATE INT INSTRUCTION)
  97.       CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;GO AHEAD AND GET THE CHARACTER
  98.       PUSHF                   ;SAVE THE FLAG RETURNED (FOR AH = 1 REQUESTS)
  99.  
  100.       CMP CS:BYTE PTR REQUEST+1,00H ;WE ARE ONLY INTERESTED IN CHAR. REQUESTS
  101.       JZ  CNTINUE
  102.       JMP FORGET_IT
  103.  
  104. CNTINUE:                      ;YES -- CHECK CHARACTER FOR 'OURS'
  105.       POPF                    ;FOR NON-TYPE 1 REQUESTS DONT NEED TO SAVE FLAGS
  106.       CMP AX,CUT_KEY
  107.       JZ  CNT_AGIN
  108.       CMP AX,PASTE_KEY
  109.       JZ  PASTE_CHAR
  110.  
  111.       JMP RETURN_CHAR
  112.  
  113. CNT_AGIN:                     ;WE GOT IT! GO INTO EDITOR MODE
  114.       MOV CS:SAVESTACK,SP
  115.       MOV CS:SAVESTACK+2,SS
  116.       MOV  AX,CS
  117.       MOV  SS,AX
  118.       MOV  SP,100H
  119.  
  120.       STI                     ;ENABLE INTERRUPTS WHILE PROCESSING CHARACTERS
  121.  
  122.       PUSH BP                 ;SET UP A STACK FRAME
  123.       MOV  BP,SP
  124.       SUB  SP,0EH
  125.       CALL SAVEREG
  126.       MOV  DS,AX
  127.  
  128.       CALL READ_CURSOR
  129.       MOV OLD_CUR_POS,DX      ;SAVE THE CURSOR FOR LATER RESTORING
  130.       MOV CURSOR_POS,DX      ;SAVE THE CURSOR FOR LATER RESTORING
  131.  
  132.       CALL CALC_WINDOW        ;CALCULATE WINDOW EXTREMETIES
  133.  
  134.       CALL WINDOW_SAVE        ;SAVE SCREEN
  135.  
  136.       MOV DX,CURSOR_POS       ;RESTORE CURSOR IN EDIT WINDOW
  137.       CALL PLACE_CURSOR
  138.  
  139.       CALL EDITOR             ;LET HIM EDIT IN THE WINDOW
  140.  
  141.       CALL READ_CURSOR
  142.       MOV CURSOR_POS,DX       ;SAVE CURSOR IN EDIT WINDOW FOR NEXT EDIT
  143.  
  144.       CALL WINDOW_SWAP        ;PUT BACK WHATEVER WAS ORIGINALLY THERE
  145.  
  146.       MOV DX,OLD_CUR_POS      ;RESTORE THE CURSOR POSITION
  147.       CALL PLACE_CURSOR
  148.  
  149.       CALL RESTREG
  150.       ADD  SP,0EH
  151.       POP  BP
  152.  
  153.       MOV SS,CS:SAVESTACK+2
  154.       MOV SP,CS:SAVESTACK
  155.  
  156.       MOV AH,00              ;RESTORE REQUEST TO SOMETHING DECENT
  157.       JMP MAINLOOP           ;GO GET ANOTHER CHARACTER TO RETURN HIM
  158.  
  159. PASTE_CHAR:
  160.       MOV  AX,CS:FEED_END1   ;BEGIN TO FEED CHARACTER STRING INTO APPLICATION
  161.       MOV  CS:FEED_START,AX
  162.       MOV  AX,CS:FEED_END2
  163.       MOV  CS:FEED_STOP,AX
  164.  
  165.       MOV AH,00              ;RESTORE REQUEST TO SOMETHING DECENT
  166.       JMP MAINLOOP           ;GO GET ANOTHER CHARACTER TO RETURN HIM
  167.  
  168. RETURN_CHAR:
  169.       IRET                   ;RETURN WITH CHARACTER
  170.  
  171. ;HANDLE REQUEST TYPE 1'S BY FAR RETURNING 2 AND TYPE 2'S BY JUST RETURNING
  172.  
  173. FORGET_IT:
  174.       CMP  CS:BYTE PTR REQUEST+1,1      ;was it a "is char present" request?
  175.       JZ   FI100
  176.  
  177.       POPF                   ;no -- just return whatever BIOS returned
  178.       IRET
  179.  
  180. FI100:
  181.       POPF                   ;yes -- make funny return
  182.       RET 02
  183.       PAGE
  184. ;HERE WE ARE IN THE PROCESS OF FEEDING CHARACTERS TO THE APPLICATION
  185. ;FROM THE WINDOW BUFFER (SCREENSAVE)
  186.  
  187. FEED:
  188.       CMP  CS:BYTE PTR REQUEST+1,1       ;WAS THIS A CHAR TYPE REQUEST?
  189.       JA   KSTAT
  190.                                 ;YES -- RETURN HIM CHAR
  191.       PUSH BX                 ;GET THE NEXT CHARACTER FROM THE BUFFER
  192.       MOV  BX,AX
  193.       MOV  AX,CS:[BX]
  194.       POP  BX
  195.       XOR  AH,AH              ;WE NO LONGER HAVE THE SCAN CODE, BUT ALL
  196.       MOV  CS:FEED_CHAR,AX    ;ARE ASCII ANYWAY
  197.  
  198.       CMP  CS:BYTE PTR REQUEST+1,0       ;IS THIS A 'GET KEYBOARD CHAR' RQST?
  199.       JNZ  FEED_KEY_STAT
  200.  
  201.       ADD  CS:FEED_START,2    ;YES -- MOVE UP THE POINTER BY 1
  202.  
  203.  
  204. ; SKIP ANY TRAILING BLANKS
  205.       PUSH BX
  206.       MOV BX,CS:FEED_START
  207. FEED10:
  208.       CMP BX,CS:FEED_STOP
  209.       JZ  FEED50
  210.       MOV AX,CS:[BX]
  211.       CMP AL,' '
  212.       JZ FEED20
  213.       CMP  AL,00DH
  214.       JNZ FEED50
  215.       MOV CS:FEED_START,BX
  216.       JMP FEED50
  217. FEED20:
  218.       INC BX
  219.       INC BX
  220.       JMP FEED10
  221. FEED50:
  222.       POP BX
  223.  
  224.       MOV AX,CS:FEED_CHAR
  225.         IRET
  226.  
  227. FEED_KEY_STAT:
  228.       STI                     ;NO -- ENABLE INTERRUPTS AND FEED HIM THE
  229.       RET  02                 ;THE Z FLAG CLEAR WITH HIS CHAR
  230.  
  231. KSTAT:
  232.       MOV  AX,CS:REQUEST      ;RESTORE REQUEST TO AH
  233.       PUSHF
  234.       CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;PERFORM BIOS CALL -- WE DON'T KNOW
  235.                                 ;WHAT HE'S DOING AND WE SHOULDN'T GET IN THE WAY
  236.       IRET                    ;RETURN THE RESULTS TO HIM (WHATEVER THEY ARE)
  237. BEGIN ENDP
  238.       PAGE
  239. BODY  PROC NEAR               ;MAKE SHORT CALLS ONLY TO THE MAIN ROUTINES
  240. CALC_WINDOW:
  241.       MOV AH,0FH              ;FIND OUT VIDEO MODE FOR CALCULATING WINDOW SIZE
  242.       INT VIDEO               ;GO AHEAD AND GET THE CHARACTER
  243.  
  244. ;***SAVE OFF THE VIDEO SEGMENT***
  245.  
  246.       MOV CX,0B000H           ;IS IT MONOCHROME?
  247.       CMP AL,7                ;WELL LOOK FOR MODE 7
  248.       JZ  CW100
  249.       MOV CX,0B800H           ;NO -- ITS GRAPHIX
  250. CW100:
  251.       MOV DISPLAY_SEG,CX      ;SAVE THIS OFF
  252. ;***
  253.  
  254.       DEC AH                  ;THIS IS THE NUMBER OF COLS ON SCREEN
  255.       MOV RIGHT_MARG,AH       ;SET UP RIGHT AND LEFT MARGINS
  256.       SUB AH,(WNDW_WD - 1)
  257.       MOV LEFT_MARG,AH
  258.  
  259.       MOV TOP_MARG,0          ;WE HAVE NO INFORMATION ON NUMBER OF ROWS
  260.       MOV BOT_MARG,WNDW_HT-1  ;SO WE MUST ASSUME SOMETHING NORMAL (IT ISNT
  261.                               ;AS CRITICAL ANYWAY)
  262.  
  263.       MOV AL,AH               ;NOW ADD UPPER_LEFT HAND CORNER VALUE
  264.       XOR AH,AH
  265.       MOV UPPER_LEFT,AX
  266.  
  267.  
  268. CW200:
  269.       RET
  270.       PAGE
  271. ;***NEW WINDOW_SWAP PROCEDURE AND WINDOW_SAVE COMBINED -- TWO DIFFERENT
  272. ;ENTRY POINTS TELL WHETHER TO DO THE WRITE OR NOT
  273. ;NOTE THAT THIS PROCEDURE DOES NOT BIOS CALLS -- ALL DIRECT WRITES
  274.  
  275. SWAP_SAVE DB 0
  276.  
  277. WINDOW_SAVE:
  278.       MOV SWAP_SAVE,0         ;MARK THIS ENTRY POINT
  279.       JMP WS025
  280.  
  281. WINDOW_SWAP:
  282.         MOV SWAP_SAVE,0FFH       ;MARK THIS DIFFERENT ENTRY POINT
  283.  
  284. WS025:
  285.         MOV CX,WNDW_HT          ;GET THE NUMBER OF ROWS IN WINDOW AREA
  286.       MOV SI,OFFSET SCREENSAVE;START AT BEGINNING OF BUFFER
  287.       MOV ES,DISPLAY_SEG      ;LOAD UP THE VIDEO SEGMENT
  288.       MOV DI,00
  289.       XOR BX,BX
  290. WS050:
  291.       MOV BL,LEFT_MARG        ;START ON THIS LINE AT THE LEFT MARGIN
  292. WS100:
  293.       SHL  BX,1               ;CHANGE THE COLUMN NUMBER TO BYTE POINTER
  294.       MOV  AX,ES:[BX][DI]     ;GET THE NEXT CHARACTER FROM SCREEN
  295.       XCHG AX,[SI]            ;STORE IT AWAY AND WRITE THE SAVED CHARACTER
  296.       ADD  SI,2               ;AND MOVE SAVE POINTER OVER A WORD
  297. ;***HERE IS THE SWAP SAVE CHECK
  298.       CMP  SWAP_SAVE,0        ;IS THIS WINDOW SWAP OR WINDOW SAVE?
  299.       JZ   WS150
  300.                                 ;MUST BE SWAP
  301.       MOV  ES:[BX][DI],AX     ;NOW RESTORE THAT CHARACTER TO THE SCREEN
  302. WS150:
  303. ;***
  304.         SHR      BX,1            ;PUT THE BYTE OFFSET BACK TO COLUMN NUMBER
  305.       INC  BX
  306.       CMP  BL,RIGHT_MARG      ;ARE WE BEYOND THE END OF THE LINE?
  307.       JNA  WS100
  308.                               ;YES -- SKIP DOWN TO NEXT LINE
  309.  
  310.       MOV WORD PTR [SI],000DH     ; SO CR'S ARE FED PROPERLY LATER
  311.       INC SI
  312.       INC SI
  313.  
  314.       SHL  BX,1               ;ADJUST DI BY ONE LINE'S WORTH SO THAT IT
  315.       ADD  DI,BX              ;POINTS TO BEGINNING OF NEXT LINE
  316.       LOOP WS050
  317.       RET
  318.       PAGE
  319. EDITOR:
  320.  
  321. ;check for edit keys (such as insert, delete, etc.)
  322. ;if not one of those, assume its ascii and just insert it in the
  323. ;screen return when AltF10 detected.
  324.  
  325. ED100:
  326.       CALL GET_CHAR         ;read a character from the keyboard
  327.       OR   AL,AL            ;if this is ascii then dont retain scan code
  328.       JZ   ED105
  329.       XOR  AH,AH
  330.  
  331. ED105:
  332.         CALL UNSHADE_SCREEN      ;REMOVE PREVIOUS SHADING (IF ANY)
  333.  
  334.       MOV  BX,CURSOR_POS     ;in many cases we need the cursor position
  335.       CMP  AX,CUT_KEY        ;check for exit
  336.       JNZ  ED110
  337.       JMP  ED800
  338.  
  339. ED110:
  340.       CMP  AX,CR             ;check for each special character individually
  341.       JNZ  ED120
  342.       MOV  BL,LEFT_MARG
  343.       INC  BH
  344.       JMP  ED500
  345. ED120:
  346.       CMP  AX,LEFT_ARROW
  347.       JNZ  ED140
  348.       DEC  BL
  349.       JMP  ED500
  350.  
  351. ED140:
  352.       CMP  AX,RIGHT_ARROW
  353.       JNZ  ED160
  354.       INC  BL
  355.       JMP  ED500
  356.  
  357. ED160:
  358.       CMP   AX,UP_ARROW
  359.       JNZ   ED180
  360.       DEC   BH
  361.       JMP   ED500
  362.  
  363. ED180:
  364.       CMP  AX,DOWN_ARROW
  365.       JNZ  ED200
  366.       INC  BH
  367.       JMP  ED500
  368.  
  369. ED200:
  370.       CMP  AX,HOME
  371.       JNZ  ED205
  372.       MOV  BX,UPPER_LEFT
  373.       JMP  ED500
  374.  
  375. ED205:                       ;tab and back tab functions
  376.       CMP  AX,TAB
  377.       JNZ  ED210
  378.       MOV  CL,1              ;go forward
  379.       JMP  ED213
  380.  
  381. ED210:
  382.       CMP  AX,REV_TAB
  383.       JNZ  ED220
  384.  
  385.       MOV  CL,0FFH           ;go backwards one tab slot
  386.       ADD  DL,CL             ;start one char to left initially
  387.  
  388. ED213:
  389.       CALL READ_CHAR         ;get char at current position
  390.       MOV  CH,AL             ;save it for comparison
  391. ED215:
  392.       ADD  DL,CL             ;move over one character
  393.       CMP  DL,RIGHT_MARG     ;stop at left and right margins (or beyond)
  394.       JGE  ED218
  395.       CMP  DL,LEFT_MARG
  396.       JLE  ED218
  397.  
  398.       CALL READ_CHAR         ;read current character
  399.       CMP  CH,' '            ;if original was a space...
  400.       JNZ  ED216
  401.       CMP  AL,' '            ;...then go until not space
  402.       JZ  ED215
  403.       JMP ED217
  404. ED216:
  405.       CMP AL,' '             ;...else, go until space
  406.       JNZ ED215
  407. ED217:
  408.       CMP  CL,0FFH           ;if we were going backwards (towards left)...
  409.       JNZ  ED218
  410.       ADD  DL,1              ;...then scoot back to the right by 1
  411. ED218:
  412.       MOV  BX,DX
  413.       JMP  ED500
  414.  
  415. ED220:
  416.       CMP  AX,ESCAPE         ;wipe out remainder of line
  417.       JNZ  ED240
  418.       MOV  DX,BX
  419.       CALL ERASE_LINE
  420.       JMP  ED500
  421.  
  422. ED240:
  423.       CMP  AX,DEL_LEFT       ;move cursor left one char and then do normal del
  424.       JNZ  ED260
  425.       DEC  BL
  426.       CMP  BL,LEFT_MARG
  427.       JNB  ED250
  428.       MOV  BL,RIGHT_MARG
  429.       CMP  BH,00
  430.       JZ   ED250
  431.       DEC  BH
  432. ED250:
  433.       JMP  ED270
  434.  
  435. ED260:
  436.       CMP  AX,DELETE         ;in delete char we...
  437.       JNZ  ED280
  438. ED270:
  439.       MOV  CL,RIGHT_MARG
  440.       SUB  CL,BL             ;calculate how many chars to right margin
  441.       XOR  CH,CH
  442.       MOV  DX,BX             ;...start at current cursor position...
  443.       JCXZ ED275
  444. ED272:
  445.       INC  DL                ;...get character just to the right...
  446.       CALL READ_CHAR
  447.       DEC  DL                ;...move left one position...
  448.       CALL WRITE_CHAR        ;...and write it there...
  449.       INC  DL                ;...now do it again for the char to the right...
  450.       LOOP ED272             ;...for the distance from cursor to right margin;...
  451. ED275:
  452.       MOV  AX,BLANK
  453.       CALL WRITE_CHAR
  454.       JMP  ED500
  455.  
  456. ED280:
  457.       CMP  AX,INSERT         ;in the case of insert we do reverse of delete
  458.       JNZ  ED300
  459.       MOV  DH,BH             ;start at the right margin
  460.       MOV  DL,RIGHT_MARG
  461.       MOV  CL,DL             ;caculate number of spaces to right
  462.       SUB  CL,BL
  463.       XOR  CH,CH
  464.       JCXZ ED290
  465. ED285:
  466.       DEC  DL
  467.       CALL READ_CHAR
  468.       INC  DL
  469.       CALL WRITE_CHAR
  470.       DEC  DL
  471.       LOOP ED285
  472. ED290:
  473.       MOV  AX,BLANK
  474.       CALL WRITE_CHAR
  475.       JMP  ED500
  476.  
  477. ED300:
  478.       CMP  AX,LINE_INS       ;check for insert line
  479.       JNZ  ED320
  480.       MOV  DH,BOT_MARG       ;we're going to need that
  481. ED305:
  482.       MOV  DL,LEFT_MARG      ;always start at the far left
  483.       CMP  DH,BH             ;are we on our current line?
  484.       JZ   ED315
  485.                              ;no -- then move it down
  486.       MOV  CX,WNDW_WD
  487. ED310:
  488.       DEC  DH
  489.       CALL READ_CHAR         ;get the character
  490.       INC  DH
  491.       CALL WRITE_CHAR        ;and put it back one line higher
  492.       INC  DL                ;move right one character
  493.       LOOP ED310
  494.  
  495.       DEC  DH                ;now move up a line and do it again
  496.       JMP  ED305
  497. ED315:
  498.       MOV  BL,LEFT_MARG      ;move us over the far left marg
  499.       CALL ERASE_LINE        ;and wipe out the line we are on
  500.       JMP  ED500
  501.  
  502. ED320:
  503.       CMP  AX,LINE_DEL       ;and check for line delete
  504.       JNZ  ED340
  505.  
  506. ED325:
  507.       MOV  DL,LEFT_MARG      ;always start at the far left
  508.       CMP  DH,BOT_MARG       ;are we on the last line?
  509.       JZ   ED335
  510.                              ;no -- then move it up
  511.       MOV  CX,WNDW_WD
  512. ED330:
  513.       INC  DH
  514.       CALL READ_CHAR         ;get the character
  515.       DEC  DH
  516.       CALL WRITE_CHAR        ;and put it back one line lower
  517.       INC  DL                ;move right one character
  518.       LOOP ED330
  519.  
  520.       INC  DH                ;now move down a line and do it again
  521.       JMP  ED325
  522. ED335:
  523.       MOV  BL,LEFT_MARG      ;move us over the far left marg of our line
  524.       CALL ERASE_LINE        ;and wipe out the bottom line
  525.       JMP  ED500
  526.  
  527. ED340:
  528.       CMP  AX,MARK_CHAR      ;check for mark
  529.       JNZ  ED400
  530.  
  531.       MOV  DX,BX
  532.       CMP  MARK,-1           ;if mark isnt set...
  533.       JNZ  ED350
  534.       MOV  MARK,BX           ;...just set it and switch its attrib
  535.       CALL READ_CHAR
  536.       MOV  AH,ATTRIB
  537.       CALL WRITE_CHAR
  538.       JMP  ED500
  539.  
  540. ED350:                       ;else, store off feed start and end addresses
  541.       CALL CONVERT_LOC
  542.       MOV  FEED_END1,AX
  543.  
  544.       MOV  DX,MARK
  545.       CALL CONVERT_LOC
  546.       MOV  FEED_END2,AX
  547.  
  548.       MOV  CX,FEED_END1
  549.       CMP  CX,AX
  550.       JNA  ED355
  551.       MOV  FEED_END1,AX
  552.       MOV  FEED_END2,CX
  553. ED355:
  554.         CALL TRIM_SCREEN ;TRIM OFF UNMARKED THINGS ON SCREEN
  555.       JMP  ED800             ;note that this char exits the utility
  556.  
  557. ED400:                       ;wasnt an edit character -- must be ascii
  558.                                 ;just write the character at current position
  559.       MOV  AH,ATTRIB
  560.       CALL W_CHAR
  561.       INC  BL                ;move over one position
  562.  
  563. ED500:                       ;adjust resulting cursor position
  564.       CMP  BL,RIGHT_MARG
  565.       JLE  ED550
  566.       MOV  BL,RIGHT_MARG
  567. ED550:
  568.       CMP  BH,BOT_MARG
  569.       JLE  ED600
  570.       MOV  BH,BOT_MARG
  571. ED600:
  572.       CMP  BL,LEFT_MARG
  573.       JGE  ED650
  574.       MOV  BL,LEFT_MARG
  575. ED650:
  576.       CMP  BH,TOP_MARG
  577.       JGE  ED700
  578.       MOV  BH,TOP_MARG
  579. ED700:
  580.       MOV  CURSOR_POS,BX
  581.       MOV  DX,BX             ;be sure and move the cursor to the new
  582.       CALL PLACE_CURSOR      ;position
  583.       JMP  ED100
  584.  
  585. ED800:                       ;exit
  586.       RET
  587.       PAGE
  588. ;
  589. ; HERE WE PLACE SOME SMALL GENERAL PURPOSE ROUTINES
  590. ;
  591.  
  592. PLACE_CURSOR:                ;place cursor at location in dx
  593.  
  594.       CALL SHADE_SCREEN       ;if we are in mark mode, set the
  595.                                 ;screen square to inverse video
  596.       MOV AH,2H
  597.       PUSH BX
  598.       XOR BX,BX
  599.       INT VIDEO
  600.       POP  BX
  601.       RET
  602.  
  603. UP_LEFT DW 0
  604. LW_RIGHT DW 0
  605. ATTRIBUTE DB 0
  606. SAVE_AX DW 0
  607. SAVE_DX DW 0
  608.  
  609. SHADE_SCREEN:                    ;NEW SCREEN SHADING PROCEDURE
  610.         CMP      MARK,-1H        ;IS A MARK SET?
  611.         JZ       SS_END
  612.                                 ;YES -- OK SWING INTO ACTION
  613.         MOV      SAVE_AX,AX
  614.         MOV      SAVE_DX,DX
  615.         MOV      ATTRIBUTE,INV_ATTRIB ;FIRST SET THE ATTRIBUTE TO INVERSE
  616.         MOV      BX,CURSOR_POS
  617.         MOV     AX,MARK         ;NOW, CALCULATE THE UPPER LEFT CORNER...
  618.         CMP      BL,AL           ;...OF OUR SHADED BOX
  619.         JA       SS100
  620.         MOV      AL,BL
  621. SS100:
  622.         CMP      BH,AH
  623.         JA       SS200
  624.         MOV      AH,BH
  625. SS200:
  626.         MOV      UP_LEFT,AX
  627.         MOV      AX,MARK ;NOW THE LOWER RIGHT CORNER
  628.         CMP      BL,AL
  629.         JB       SS300
  630.         MOV      AL,BL
  631. SS300:
  632.         CMP      BH,AH
  633.         JB       SS400
  634.         MOV      AH,BH
  635. SS400:
  636.         MOV      LW_RIGHT,AX
  637.         JMP      SS_COMMON
  638.  
  639. UNSHADE_SCREEN:
  640.         CMP      MARK,-1H        ;HERE WE UNSHADE THE SHADED AREA
  641.         JZ       SS_END
  642.         MOV      SAVE_AX,AX
  643.         MOV      SAVE_DX,DX
  644.         MOV      ATTRIBUTE,ATTRIB ;CHANGE THE BOX BACK TO NORMAL
  645.  
  646.  
  647. ;NOW BEGIN TO SHADE IN FROM THE UPPER LEFT TO THE LOWER RIGHT CORNERS
  648.  
  649. SS_COMMON:
  650.         MOV      DX,UP_LEFT
  651.         MOV      BX,LW_RIGHT
  652. SS500:
  653.         CMP      DL,BL                   ;ARE WE OFF THE RIGHT END?
  654.         JA       SS600
  655.         MOV      AH,ATTRIBUTE
  656.         CALL     WRITE_ATTRIB
  657.         INC      DL
  658.         JMP      SS500
  659. SS600:
  660.         INC      DH                      ;OK WE WENT OFF THE RIGHT END...
  661.         CMP      DH,BH                   ;...MOVE DOWN ONE AND CHECK LOWER BOUND
  662.         JA       SS700
  663.         MOV      DL,BYTE PTR UP_LEFT
  664.         JMP      SS500
  665. SS700:
  666.         MOV      AX,SAVE_AX
  667.         MOV      DX,SAVE_DX
  668. SS_END:
  669.         RET
  670.  
  671. TRIM_SCREEN:                             ;AFTER HE SELECTS THE SECOND MARK
  672.                                         ;WE TRIM OFF THE RIGHT MARG OF SCREEN
  673.         MOV      MARK,-1H                ;FIRST CLEAR MARK
  674.         MOV      BX,UP_LEFT              ;START WITH THE FIRST LINE
  675.         MOV      BL,BYTE PTR LW_RIGHT
  676. TS100:
  677.         MOV      DX,LW_RIGHT             ;COMPARE THIS WITH THE LAST LINE
  678.         CMP      BH,DH                   ;FINISHED?
  679.         JZ       TS200
  680.         MOV      DX,BX                   ;NO -- ERASE THE END OF THIS LINE
  681.         CALL     ERASE_LINE
  682.         INC      BH                      ;AND CONTINUE ON TO NEXT LINE
  683.         JMP      TS100
  684. TS200:
  685.         RET
  686.  
  687. READ_CURSOR:                  ;read cursor location into dx
  688.       MOV AH,3H
  689.       PUSH BX
  690.       XOR BX,BX
  691.       INT VIDEO
  692.       POP  BX
  693.       RET
  694.  
  695. ;***NEW READ CHAR PROCEDURE***
  696. READ_CHAR:                    ;read screen character at location in dx
  697.       CALL CALC_VID_LOC       ;covert the row and column into location
  698.       MOV  AX,ES:[DI]         ;get the character at that location
  699.       RET
  700. ;***
  701.  
  702. R_CHAR:                       ;read screen char at current cursor location
  703.       MOV AH,8H
  704.       PUSH BX
  705.       XOR BH,BH
  706.       INT VIDEO
  707.       POP  BX
  708.       RET
  709.  
  710. ;***NEW WRITE CHAR PROCEDURE
  711. WRITE_CHAR:                   ;write attrib/char in ax at location in dx
  712.       PUSH AX                 ;save the attrib from destruction
  713.       CALL CALC_VID_LOC       ;convert the row and column into location
  714.       POP  AX
  715.       MOV ES:[DI],AX
  716.       RET
  717. WRITE_ATTRIB:
  718.       PUSH AX
  719.       CALL CALC_VID_LOC
  720.       POP  AX
  721.         MOV ES:01[DI],AH
  722.       RET
  723. ;***
  724.  
  725. W_CHAR:                       ;write character at current cursor location
  726.       PUSH BX                 ;save bx register
  727.       MOV  BL,AH
  728.       XOR  BH,BH
  729.       PUSH CX                 ;retain cx register also
  730.       MOV  CX,1
  731.       MOV  AH,9H
  732.       INT VIDEO
  733.       POP  CX
  734.       POP  BX
  735.       RET
  736.  
  737. GET_CHAR:                     ;get character from keyboard into ax
  738.       MOV AH,0H
  739.       PUSHF                   ;simulate call to keyboard handler
  740.       CALL DWORD PTR [KEY_RQST_HANDLER]
  741.       RET
  742.  
  743. ERASE_LINE:                   ;erase the current line from dx to right margin
  744.       MOV  CL,RIGHT_MARG
  745.       SUB  CL,BL
  746.       INC  CL
  747.       XOR  CH,CH
  748.       MOV  SI,OFFSET LINESAVE
  749.  
  750. ER100:
  751.       CALL READ_CHAR         ;get the character @ current location
  752.       MOV  [SI],AX
  753.       ADD  SI,2
  754.  
  755.       MOV  AX,BLANK
  756.       CALL WRITE_CHAR        ;***CHANGED FROM W_CHAR***
  757.       INC  DL
  758.       LOOP ER100
  759.       RET
  760.  
  761. RESTORE_LINE:                ;restore the current line from dx to right margin
  762.       MOV  CL,RIGHT_MARG
  763.       SUB  CL,BL
  764.       INC  CL
  765.       XOR  CH,CH
  766.       MOV  DI,OFFSET LINESAVE
  767.  
  768. RL100:
  769.       MOV  AX,[DI]           ;get the saved char
  770.       CALL WRITE_CHAR         ;put the saved char where indicated
  771.       ADD  DI,2
  772.       INC  DL
  773.       LOOP RL100
  774.       RET
  775.  
  776. CONVERT_LOC:                 ;convert a location on the screen (in dx) into AX
  777.       MOV  CX,DX
  778.       MOV  AX,OFFSET SCREENSAVE
  779. CL100:
  780.       CMP  CH,TOP_MARG
  781.       JZ   CL200
  782.       ADD  AX,(WNDW_WD+1)*2
  783.       DEC  CH
  784.       JMP  CL100
  785.  
  786. CL200:
  787.       CMP  CL,LEFT_MARG
  788.       JZ   CL300
  789.       ADD  AX,2
  790.       DEC  CL
  791.       JMP  CL200
  792.  
  793. CL300:
  794.       RET
  795.  
  796. SAVEREG:
  797.       MOV  -2[BP],BX          ;save reggies on stack frame
  798.       MOV  -4[BP],CX
  799.       MOV  -6[BP],DX
  800.       MOV  -8[BP],SI
  801.       MOV  -0AH[BP],DI
  802.       MOV  -0CH[BP],DS
  803.       MOV  -0EH[BP],ES       ;***ADDED SAVING OF ES***
  804.       RET
  805. RESTREG:
  806.       MOV  BX,-2[BP]          ;NOW PUT THE REGGIES BACK AND PULL DOWN
  807.       MOV  CX,-4[BP]          ;THE STACK FRAME
  808.       MOV  DX,-6[BP]
  809.       MOV  SI,-8[BP]
  810.       MOV  DI,-0AH[BP]
  811.       MOV  DS,-0CH[BP]
  812.       MOV  ES,-0EH[BP]       ;***ADD RESTORE OF ES***
  813.       RET
  814.  
  815. ;***NEW PROCEDURE TO CONVERT ROW AND COLUMN INTO ADDRESS
  816.  
  817. CALC_VID_LOC:                ;convert the row and column in dx into an
  818.                              ;offset into the video display buffer
  819.       XOR  AX,AX
  820.       XOR  DI,DI
  821.       PUSH CX                ;save cx -- some of those who call us need it
  822.       XOR  CX,CX
  823.  
  824.       MOV  AL,RIGHT_MARG     ;get the width of a row
  825.       INC  AX
  826.       MOV  CL,DH             ;put the number of rows into cx
  827.       JCXZ CVL200
  828. CVL100:
  829.       ADD  DI,AX             ;for every row add in another 80/40 columns
  830.       LOOP CVL100
  831. CVL200:
  832.       MOV  AL,DL             ;now move over to the current column
  833.       ADD  DI,AX
  834.  
  835.       POP  CX                ;restore cx
  836.  
  837.       SHL  DI,1              ;now convert this into byte offset
  838.       MOV  ES,DISPLAY_SEG
  839.       RET
  840. ;***
  841.  
  842. BODY  ENDP
  843.       PAGE
  844. INSTALL:
  845. ;THIS PROGRAM INSTALLS THE REST OF THE CODE FOR CUTPASTE
  846.  
  847.       MOV DX,OFFSET MESSAGE  ;OUTPUT 'OK' MESSAGE
  848.       MOV AH,9H
  849.       INT 21H
  850.  
  851.       MOV AX,3516H            ;GET INTERRUPT 16 VECTOR
  852.       INT 21H
  853.       MOV WORD PTR KEY_RQST_HANDLER,BX
  854.       MOV WORD PTR KEY_RQST_HANDLER+2,ES
  855.  
  856.       MOV AX,2516H
  857.       MOV DX,OFFSET BEGIN     ;NOW PUT OUR ROUTINE THERE
  858.       INT 21H
  859.  
  860.       MOV DX,OFFSET INSTALL   ;TERMINATE AND STAY RESIDENT
  861.       ADD DX,100H
  862.       MOV CL,4
  863.       SHR DX,CL
  864.       MOV AH,31H
  865.       INT 21H
  866.  
  867. MESSAGE DB 10,13,'CUTPASTE 4.0 installed',10,13,' ALT F9 to enable cut', ; WARREN
  868.         DB 10,13,'   ^F9 to paste   ',10,13,'$'
  869.  
  870. CSEG ENDS
  871.      END START
  872.